<template>
  <div class="time-picker-wrapper">
    <div
      class="time-picker-input"
      :class="{
        active: visible,
        range: isRange,
        disabled: disabled,
      }"
      @click="togglePanel"
    >
      <div class="time-display">
        <span v-if="!isRange">{{ displayValue || placeholder }}</span>
        <div v-else class="range-display">
          <span>{{ displayStartTime || startPlaceholder }}</span>
          <span class="separator">至</span>
          <span>{{ displayEndTime || endPlaceholder }}</span>
        </div>
      </div>
      <div class="time-icon iconfont icon-time"></div>
    </div>

    <transition name="fade">
      <div v-if="visible" class="time-panel" @click.stop>
        <div v-if="!isRange" class="single-time">
          <div class="time-columns">
            <div class="time-column">
              <div class="column-title">时</div>
              <div class="time-list">
                <div
                  v-for="h in 24"
                  :key="h - 1"
                  class="time-item"
                  :class="{ active: hour === h - 1 }"
                  @click="setHour(h - 1)"
                >
                  {{ String(h - 1).padStart(2, "0") }}
                </div>
              </div>
            </div>
            <div class="time-column">
              <div class="column-title">分</div>
              <div class="time-list">
                <div
                  v-for="m in 60"
                  :key="m - 1"
                  class="time-item"
                  :class="{ active: minute === m - 1 }"
                  @click="setMinute(m - 1)"
                >
                  {{ String(m - 1).padStart(2, "0") }}
                </div>
              </div>
            </div>
            <div class="time-column" v-if="showSeconds">
              <div class="column-title">秒</div>
              <div class="time-list">
                <div
                  v-for="s in 60"
                  :key="s - 1"
                  class="time-item"
                  :class="{ active: second === s - 1 }"
                  @click="setSecond(s - 1)"
                >
                  {{ String(s - 1).padStart(2, "0") }}
                </div>
              </div>
            </div>
          </div>
        </div>

        <div v-else class="range-time">
          <div class="range-panels">
            <!-- 开始时间面板 -->
            <div class="time-panel-section">
              <div class="panel-title">开始时间</div>
              <div class="time-columns">
                <div class="time-column">
                  <div class="column-title">时</div>
                  <div class="time-list">
                    <div
                      v-for="h in 24"
                      :key="h - 1"
                      class="time-item"
                      :class="{ active: startHour === h - 1 }"
                      @click="setStartHour(h - 1)"
                    >
                      {{ String(h - 1).padStart(2, "0") }}
                    </div>
                  </div>
                </div>
                <div class="time-column">
                  <div class="column-title">分</div>
                  <div class="time-list">
                    <div
                      v-for="m in 60"
                      :key="m - 1"
                      class="time-item"
                      :class="{ active: startMinute === m - 1 }"
                      @click="setStartMinute(m - 1)"
                    >
                      {{ String(m - 1).padStart(2, "0") }}
                    </div>
                  </div>
                </div>
                <div class="time-column" v-if="showSeconds">
                  <div class="column-title">秒</div>
                  <div class="time-list">
                    <div
                      v-for="s in 60"
                      :key="s - 1"
                      class="time-item"
                      :class="{ active: startSecond === s - 1 }"
                      @click="setStartSecond(s - 1)"
                    >
                      {{ String(s - 1).padStart(2, "0") }}
                    </div>
                  </div>
                </div>
              </div>
            </div>

            <!-- 结束时间面板 -->
            <div class="time-panel-section">
              <div class="panel-title">结束时间</div>
              <div class="time-columns">
                <div class="time-column">
                  <div class="column-title">时</div>
                  <div class="time-list">
                    <div
                      v-for="h in 24"
                      :key="h - 1"
                      class="time-item"
                      :class="{
                        active: endHour === h - 1,
                        disabled: isEndHourDisabled(h - 1),
                      }"
                      @click="setEndHour(h - 1)"
                    >
                      {{ String(h - 1).padStart(2, "0") }}
                    </div>
                  </div>
                </div>
                <div class="time-column">
                  <div class="column-title">分</div>
                  <div class="time-list">
                    <div
                      v-for="m in 60"
                      :key="m - 1"
                      class="time-item"
                      :class="{
                        active: endMinute === m - 1,
                        disabled: isEndMinuteDisabled(m - 1),
                      }"
                      @click="setEndMinute(m - 1)"
                    >
                      {{ String(m - 1).padStart(2, "0") }}
                    </div>
                  </div>
                </div>
                <div class="time-column" v-if="showSeconds">
                  <div class="column-title">秒</div>
                  <div class="time-list">
                    <div
                      v-for="s in 60"
                      :key="s - 1"
                      class="time-item"
                      :class="{
                        active: endSecond === s - 1,
                        disabled: isEndSecondDisabled(s - 1),
                      }"
                      @click="setEndSecond(s - 1)"
                    >
                      {{ String(s - 1).padStart(2, "0") }}
                    </div>
                  </div>
                </div>
              </div>
            </div>
          </div>
        </div>

        <div class="time-footer">
          <button class="btn btn-cancel" @click="cancel">取消</button>
          <button class="btn btn-confirm" @click="confirm">确定</button>
        </div>
      </div>
    </transition>

    <div v-if="visible" class="overlay" @click="togglePanel"></div>
  </div>
</template>

<script>
export default {
  name: "TimeSelectComponent",
  props: {
    modelValue: {
      type: [String, Array],
      default: "",
    },
    placeholder: {
      type: String,
      default: "请选择时间",
    },
    startPlaceholder: {
      type: String,
      default: "开始时间",
    },
    endPlaceholder: {
      type: String,
      default: "结束时间",
    },
    isRange: {
      type: Boolean,
      default: false,
    },
    showSeconds: {
      type: Boolean,
      default: false,
    },
    disabled: {
      type: Boolean,
      default: false,
    },
  },
  emits: ["update:modelValue", "change"],
  data () {
    return {
      visible: false,
      hour: 0,
      minute: 0,
      second: 0,
      startHour: 0,
      startMinute: 0,
      startSecond: 0,
      endHour: 0,
      endMinute: 0,
      endSecond: 0,
    };
  },
  computed: {
    displayValue () {
      if (!this.modelValue) return "";
      return this.modelValue;
    },
    displayStartTime () {
      if (!this.isRange || !this.modelValue?.[0]) return "";
      return this.modelValue[0];
    },
    displayEndTime () {
      if (!this.isRange || !this.modelValue?.[1]) return "";
      return this.modelValue[1];
    },
  },
  watch: {
    modelValue: {
      handler (val) {
        this.initFromValue(val);
      },
      immediate: true,
    },
  },
  methods: {
    togglePanel () {
      if (this.disabled) return;
      this.visible = !this.visible;
    },

    initFromValue (val) {
      if (!val) return;

      if (this.isRange && Array.isArray(val)) {
        if (val[0]) {
          const [h, m, s] = val[0].split(":");
          this.startHour = parseInt(h) || 0;
          this.startMinute = parseInt(m) || 0;
          this.startSecond = parseInt(s) || 0;
        }
        if (val[1]) {
          const [h, m, s] = val[1].split(":");
          this.endHour = parseInt(h) || 0;
          this.endMinute = parseInt(m) || 0;
          this.endSecond = parseInt(s) || 0;
        }
      } else if (!this.isRange && typeof val === "string") {
        const parts = val.split(":");
        this.hour = parseInt(parts[0]) || 0;
        this.minute = parseInt(parts[1]) || 0;
        this.second = parseInt(parts[2]) || 0;
      }
    },

    setHour (h) {
      this.hour = h;
    },
    setMinute (m) {
      this.minute = m;
    },
    setSecond (s) {
      this.second = s;
    },
    setStartHour (h) {
      this.startHour = h;
    },
    setStartMinute (m) {
      this.startMinute = m;
    },
    setStartSecond (s) {
      this.startSecond = s;
    },

    setEndHour (h) {
      if (this.isEndHourDisabled(h)) return;
      this.endHour = h;
    },

    setEndMinute (m) {
      if (this.isEndMinuteDisabled(m)) return;
      this.endMinute = m;
    },

    setEndSecond (s) {
      if (this.isEndSecondDisabled(s)) return;
      this.endSecond = s;
    },

    isEndHourDisabled (h) {
      return h < this.startHour;
    },

    isEndMinuteDisabled (m) {
      return this.endHour === this.startHour && m <= this.startMinute;
    },

    isEndSecondDisabled (s) {
      return (
        this.endHour === this.startHour &&
        this.endMinute === this.startMinute &&
        s <= this.startSecond
      );
    },

    formatTime (h, m, s) {
      const hour = String(h).padStart(2, "0");
      const minute = String(m).padStart(2, "0");
      const second = String(s || 0).padStart(2, "0");
      return this.showSeconds
        ? `${hour}:${minute}:${second}`
        : `${hour}:${minute}`;
    },

    confirm () {
      let value;
      if (this.isRange) {
        value = [
          this.formatTime(this.startHour, this.startMinute, this.startSecond),
          this.formatTime(this.endHour, this.endMinute, this.endSecond),
        ];
      } else {
        value = this.formatTime(this.hour, this.minute, this.second);
      }

      this.$emit("update:modelValue", value);
      this.$emit("change", value);
      this.visible = false;
    },

    cancel () {
      this.initFromValue(this.modelValue);
      this.visible = false;
    },
  },
};
</script>

<style lang="less" scoped>
@primary-color: #4b58dc;

.time-picker-wrapper {
  position: relative;
  display: inline-block;

  .time-picker-input {
    display: flex;
    align-items: center;
    padding: 8px 16px;
    border: 1px solid #dcdfe6;
    border-radius: 4px;
    cursor: pointer;
    transition: all 0.3s ease;
    background: #fff;
    min-width: 150px;
    position: relative;
    overflow: hidden;

    &:hover:not(.disabled) {
      border-color: @primary-color;
      box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1);
      transform: translateY(-2px);

      &:after {
        transform: translateX(120%) skewX(-15deg);
      }
    }

    &:after {
      content: "";
      position: absolute;
      top: 0;
      left: -75%;
      width: 50%;
      height: 100%;
      background: linear-gradient(
        to right,
        rgba(255, 255, 255, 0),
        rgba(255, 255, 255, 0.4),
        rgba(255, 255, 255, 0)
      );
      transform: skewX(-15deg);
      transition: all 0.5s ease;
    }

    &.active {
      border-color: @primary-color;
      background: linear-gradient(
        to right,
        rgba(75, 88, 220, 0.05),
        rgba(75, 88, 220, 0.02)
      );
    }

    &.disabled {
      cursor: not-allowed;
      opacity: 0.6;
      background: #f5f7fa;
    }

    &.range {
      min-width: 240px;
    }

    .time-display {
      flex: 1;
      color: #606266;
      font-size: 14px;

      .range-display {
        display: flex;
        align-items: center;
        gap: 8px;

        .separator {
          color: #909399;
          font-size: 12px;
        }
      }
    }

    .time-icon {
      margin-left: 8px;
      color: #c0c4cc;
      font-size: 14px;
    }
  }

  .overlay {
    position: fixed;
    top: 0;
    left: 0;
    right: 0;
    bottom: 0;
    z-index: 1000;
  }

  .time-panel {
    position: absolute;
    top: calc(100% + 8px);
    left: 0;
    background: #fff;
    border: 1px solid @primary-color;
    border-radius: 8px;
    box-shadow: 0 8px 32px rgba(0, 0, 0, 0.15);
    z-index: 1001;
    min-width: 100%;

    .single-time {
      padding: 20px;
    }

    .range-time {
      padding: 20px;

      .range-panels {
        min-width: 500px;
      }
    }

    .range-panels {
      display: flex;
      gap: 24px;

      .time-panel-section {
        flex: 1;

        .panel-title {
          font-size: 14px;
          color: @primary-color;
          margin-bottom: 12px;
          font-weight: 500;
          text-align: center;
          padding-bottom: 8px;
          border-bottom: 1px solid #eee;
        }
      }
    }

    .time-columns {
      display: flex;
      gap: 12px;

      .time-column {
        flex: 1;

        .column-title {
          text-align: center;
          padding: 8px;
          font-size: 14px;
          color: #666;
          font-weight: 500;
          border-bottom: 1px solid #eee;
          margin-bottom: 8px;
        }

        .time-list {
          max-height: 200px;
          overflow-y: auto;
          border-radius: 4px;

          &::-webkit-scrollbar {
            width: 4px;
          }

          &::-webkit-scrollbar-thumb {
            background: @primary-color;
            border-radius: 2px;
          }

          .time-item {
            text-align: center;
            padding: 8px 12px;
            cursor: pointer;
            font-size: 14px;
            color: #606266;
            transition: all 0.3s ease;
            border-radius: 4px;
            margin: 2px;

            &:hover:not(.disabled) {
              background: lighten(@primary-color, 40%);
              color: @primary-color;
              transform: translateX(2px);
            }

            &.active {
              background: @primary-color;
              color: #fff;
              font-weight: 500;
              box-shadow: 0 2px 8px rgba(75, 88, 220, 0.3);
            }

            &.disabled {
              cursor: not-allowed;
              opacity: 0.5;
              color: #c0c4cc;
            }
          }
        }
      }
    }

    .time-footer {
      padding: 12px 20px;
      border-top: 1px solid #eee;
      display: flex;
      justify-content: flex-end;
      gap: 12px;

      .btn {
        padding: 6px 16px;
        border-radius: 4px;
        font-size: 14px;
        cursor: pointer;
        transition: all 0.3s ease;
        border: 1px solid #dcdfe6;

        &.btn-cancel {
          background: #fff;
          color: #606266;

          &:hover {
            border-color: @primary-color;
            color: @primary-color;
          }
        }

        &.btn-confirm {
          background: @primary-color;
          color: #fff;
          border-color: @primary-color;

          &:hover {
            background: lighten(@primary-color, 10%);
            transform: translateY(-1px);
            box-shadow: 0 4px 12px rgba(75, 88, 220, 0.4);
          }
        }
      }
    }
  }
}

.fade-enter-active,
.fade-leave-active {
  transition: all 0.3s cubic-bezier(0.68, -0.55, 0.27, 1.55);
}

.fade-enter-from {
  opacity: 0;
  transform: translateY(-10px) scale(0.9);
}

.fade-leave-to {
  opacity: 0;
  transform: translateY(-10px) scale(0.9);
}
</style>
